package com.chixing.service.impl;

import com.chixing.mapper.CustomerMapper;
import com.chixing.mapper.NotesPraiseMapper;
import com.chixing.mapper.TravelNotesMapper;
import com.chixing.mapper.TravelSightsMapper;
import com.chixing.pojo.*;
import com.chixing.service.IndexService;
import com.chixing.util.ServerResponse;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class IndexServiceImpl implements IndexService {
    @Autowired
    private TravelNotesMapper travelNotesMapper;
    @Autowired
    private TravelSightsMapper travelSightsMapper;
    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private NotesPraiseMapper notesPraiseMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public ServerResponse getNotesById(Integer notes_id) {
        TravelNotes notes = travelNotesMapper.selectByPrimaryKey(notes_id);
        if (notes == null) {
            return ServerResponse.getFail(null);
        } else {
            return ServerResponse.getSuccess(notes);
        }
    }

    @Override
    public ServerResponse getNotesAll() {
        TravelNotesExample example = new TravelNotesExample();
        example.createCriteria();
        List<TravelNotes> travelNotes = travelNotesMapper.selectByExample(example);
        if (travelNotes != null && travelNotes.size() > 0) {
            return ServerResponse.getSuccess(travelNotes);
        } else {
            return ServerResponse.getFail(null);
        }
    }

    @Override
    public ServerResponse getNotesByPage(Integer pageNum, Integer custId) {
        ArrayList<SightsNotesCustVO> listVo = new ArrayList<>();
        Page page = PageHelper.startPage(pageNum, 4);
        List<TravelNotes> travelNotes = travelNotesMapper.selectByExample(null);
        for (TravelNotes note : travelNotes) {
            SightsNotesCustVO sightsNotesCustVO = new SightsNotesCustVO();
            sightsNotesCustVO.setTravelNotes(note);
            Customer customer = customerMapper.selectByPrimaryKey(note.getCustId());
            sightsNotesCustVO.setCustomer(customer);
            TravelSights travelSights = travelSightsMapper.selectByPrimaryKey(note.getSightsId());
            sightsNotesCustVO.setTravelSights(travelSights);
            listVo.add(sightsNotesCustVO);
            //游记加载并且存储到redis中key=游记id:value=游记点赞数
            ValueOperations ops = redisTemplate.opsForValue();
            ops.set(note.getTravelNotesId(), note.getTravelNotesPraiseCount());

            if (custId != 0) {
                NotesPraiseExample notesPraiseExample = new NotesPraiseExample();
                notesPraiseExample.createCriteria().andTravelNotesIdEqualTo(note.getTravelNotesId())
                        .andCustIdEqualTo(custId).andNotesPraiseStatusEqualTo(0);
                List<NotesPraise> notesPraises = notesPraiseMapper.selectByExample(notesPraiseExample);
                if (notesPraises.size() != 0) {
                    //存在当前用户游记点赞对象，存入redis
                    String key = custId + ":" + notesPraises.get(0).getTravelNotesId();
                    ops.set(key, notesPraises.get(0));
                    sightsNotesCustVO.setNotesPraise(notesPraises.get(0));
                } else {
                    sightsNotesCustVO.setNotesPraise(null);
                }
            } else {
                sightsNotesCustVO.setNotesPraise(null);
            }

        }
        PageInfo pageInfo = page.toPageInfo();
        pageInfo.setList(listVo);
        return ServerResponse.getSuccess(pageInfo);
    }

    @Override
    public ServerResponse getNotesByPageOrderByDate(Integer pageNum) {
        ArrayList<SightsNotesCustVO> listVo = new ArrayList<>();
        Page page = PageHelper.startPage(pageNum, 4);
        TravelNotesExample example = new TravelNotesExample();
        example.setOrderByClause("travel_notes_date desc");
        List<TravelNotes> travelNotes = travelNotesMapper.selectByExample(example);
        for (TravelNotes note : travelNotes) {
            SightsNotesCustVO sightsNotesCustVO = new SightsNotesCustVO();
            sightsNotesCustVO.setTravelNotes(note);
            Customer customer = customerMapper.selectByPrimaryKey(note.getCustId());
            sightsNotesCustVO.setCustomer(customer);
            TravelSights travelSights = travelSightsMapper.selectByPrimaryKey(note.getSightsId());
            sightsNotesCustVO.setTravelSights(travelSights);
            listVo.add(sightsNotesCustVO);
        }
        PageInfo pageInfo = page.toPageInfo();
        pageInfo.setList(listVo);
        return ServerResponse.getSuccess(pageInfo);
    }

//    @Override
//    public ServerResponse updatePriseAdd(Integer id) {
//        TravelNotes travelNotes = travelNotesMapper.selectByPrimaryKey(id);
//        travelNotes.setTravelNotesPraiseCount(travelNotes.getTravelNotesPraiseCount()+1);
//        int i = travelNotesMapper.updateByPrimaryKey(travelNotes);
//        if(i>0){
//            return ServerResponse.updateSuccess(travelNotes);
//        }else {
//            return ServerResponse.updateFail(null);
//        }
//    }

    @Override
    public ServerResponse getNotesDetailById(Integer id) {
        TravelNotes notes = travelNotesMapper.selectByPrimaryKey(id);
        if (notes == null) {
            return ServerResponse.getFail(null);
        } else {
            return ServerResponse.getSuccess(notes);
        }
    }

    @Override
    public void praise(Integer cusId, Integer travelNotesId, Integer status) {
        ValueOperations ops = redisTemplate.opsForValue();
        String key = cusId.toString() + ":" + travelNotesId.toString();
        //带:存储的是点赞对象
        if (ops.getOperations().hasKey(key)) {
            NotesPraise notesPraise = (NotesPraise) ops.get(key);
            //redis中的点赞对象status！= 数据库中的
            if (notesPraise.getNotesPraiseStatus() != status) {
                //status = 0，表示点赞，点赞数加1
                if (status == 0) {
                    Integer o = (Integer) ops.get(travelNotesId);
                    ops.set(travelNotesId, o + 1);
                    System.out.println("点赞数增加");

                    TravelNotes travelNotes = travelNotesMapper.selectByPrimaryKey(travelNotesId);
                    travelNotes.setTravelNotesPraiseCount(o + 1);
                    travelNotesMapper.updateByPrimaryKey(travelNotes);

                    NotesPraiseExample notesPraiseExample = new NotesPraiseExample();
                    notesPraiseExample.createCriteria().andCustIdEqualTo(cusId).andTravelNotesIdEqualTo(travelNotesId);
                    NotesPraise notesPraise1 = notesPraiseMapper.selectByExample(notesPraiseExample).get(0);
                    notesPraise1.setNotesPraiseStatus(0);
                    notesPraiseMapper.updateByPrimaryKey(notesPraise1);
                } else {
                    Integer o = (Integer) ops.get(travelNotesId);
                    ops.set(travelNotesId, o - 1);
                    System.out.println("点赞数减少");

                    TravelNotes travelNotes = travelNotesMapper.selectByPrimaryKey(travelNotesId);
                    travelNotes.setTravelNotesPraiseCount(o - 1);
                    travelNotesMapper.updateByPrimaryKey(travelNotes);

                    NotesPraiseExample notesPraiseExample = new NotesPraiseExample();
                    notesPraiseExample.createCriteria().andCustIdEqualTo(cusId).andTravelNotesIdEqualTo(travelNotesId);
                    NotesPraise notesPraise1 = notesPraiseMapper.selectByExample(notesPraiseExample).get(0);
                    notesPraise1.setNotesPraiseStatus(1);
                    notesPraiseMapper.updateByPrimaryKey(notesPraise1);
                }
                notesPraise.setNotesPraiseStatus(status);
                notesPraise.setNotesPraiseTime(new Date());
                ops.set(key, notesPraise);
            }
        } else {
            //redis中不存在对象
            NotesPraise notesPraise = new NotesPraise();
            notesPraise.setCustId(cusId);
            notesPraise.setTravelNotesId(travelNotesId);
            notesPraise.setNotesPraiseTime(new Date());
            notesPraise.setNotesPraiseStatus(status);

            notesPraiseMapper.insert(notesPraise);

            ops.set(key, notesPraise, 3, TimeUnit.MINUTES);

            Integer o = (Integer) ops.get(travelNotesId);
            ops.set(travelNotesId, o + 1);

            TravelNotes travelNotes = travelNotesMapper.selectByPrimaryKey(travelNotesId);
            travelNotes.setTravelNotesPraiseCount(o + 1);
            travelNotesMapper.updateByPrimaryKey(travelNotes);
        }


    }

    @Override
    @Scheduled(cron = "0 */1 * * * ?") //每1秒执行一次
    public void reids2MySql() {
        Set<String> keys = redisTemplate.keys("*");
//        System.out.println(keys.size());//0
        ValueOperations operations = redisTemplate.opsForValue();

        for (String key : keys) {
            System.out.println("key:" + key);
            //存储 用户id 游记id 点赞状态
            if (key.contains(":")) {
                String[] split = key.split(":");
                NotesPraise notesPraise = (NotesPraise) operations.get(key);
                NotesPraiseExample notesPraiseExample = new NotesPraiseExample();
                notesPraiseExample.createCriteria().andCustIdEqualTo(Integer.valueOf(split[0])).andTravelNotesIdEqualTo(Integer.valueOf(split[1]));
                List<NotesPraise> notesPraises = notesPraiseMapper.selectByExample(notesPraiseExample);
                TravelNotes travelNotes = travelNotesMapper.selectByPrimaryKey(Integer.valueOf(split[1]));
                if (travelNotes != null) {
                    if (notesPraises.size() == 0) {
                        //数据库不存在当前游记点赞对象，insert
                        if (notesPraise.getNotesPraiseStatus() == 0) {
                            notesPraiseMapper.insert(notesPraise);
                            System.out.println("数据库插入");
                        }
                    } else {
                        //存在,点赞状态不同，更新
                        if (notesPraise.getNotesPraiseStatus() != notesPraises.get(0).getNotesPraiseStatus()) {
                            notesPraises.get(0).setNotesPraiseStatus(notesPraise.getNotesPraiseStatus());
                            notesPraiseMapper.updateByPrimaryKey(notesPraises.get(0));
                            System.out.println("数据库更新");
                        }
                    }
                } else {

                }
            } else {
                //数据库更新点赞数
                TravelNotes travelNotes = travelNotesMapper.selectByPrimaryKey(Integer.valueOf(key));
                if (travelNotes != null) {
                    Integer praiseCount = (Integer) operations.get(key);
                    if (praiseCount != travelNotes.getTravelNotesPraiseCount()) {
                        travelNotes.setTravelNotesPraiseCount(praiseCount);
                        travelNotesMapper.updateByPrimaryKey(travelNotes);
                        System.out.println(key + ":" + operations.get(key));
                        System.out.println("更新点赞数");
                    }
                } else {
                    redisTemplate.delete(key);
                    System.out.println("不存在游记对象删除");
                }
            }
        }

    }

}
